from django.db.models import Prefetch
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet

from activity.models import Activity
from activity.serializers import ActivityListSerializer
from users.models import User
from .serializers import CategoryListSerializer, NewsListSerializer, ActivityList2Serializer, \
    AnswersListSerializer, NewsDetailSerializer, AuthorRecentSerializer, HotRecommendSerializer
from .models import Category, News, Comment
from . import serializers


# Create your views here.


class CategoryViewSet(GenericViewSet, mixins.CreateModelMixin, mixins.ListModelMixin):
    """首页新闻专栏类视图"""
    pagination_class = None
    serializer_class = CategoryListSerializer
    permission_classes = [IsAuthenticated]
    # 查询集优化(只查询字段id,name)
    queryset = Category.objects.filter(is_delete=False).only('id', 'name')
    
    def get_permissions(self):
        """设置该视图集请求方法为ｇｅｔ"""
        if self.request.method == 'GET':
            return []
        return super(CategoryViewSet, self).get_permissions()


# url(r'^categories/(?P<category_id>\d+)/newslist', viwes.NewsListView.as_view())
class NewsListView(ListAPIView):
    """首页新闻列表类视图"""
    serializer_class = NewsListSerializer

    def get_queryset(self):
        """根据分类id设置不同的查询条件"""
        category_id = self.kwargs['category_id']
        # 如果分类id为１，按点击量最高排序
        if category_id == '1':
            # 查询语句优化,和用户表进行 INNER JOIN关联查询 降低查询次数，节省数据库性能开销
            return News.objects.filter(status=1).order_by('-click_count').select_related()
        return News.objects.filter(category_id=category_id, status=1).order_by('-create_time').select_related()


class ActivityList2View(ListAPIView):
    """首页活动推荐类视图"""
    serializer_class = ActivityList2Serializer
    # 查询集优化(只查询字段id,image_url)
    queryset = Activity.objects.filter(on_deleted=False).order_by('-published_time').only('id', "image_url")[0:2]


class AnswersListView(ListAPIView):
    """首页热门回答类视图"""
    serializer_class = AnswersListSerializer

# TODO 回答数据库模型类还没创建好,待处理
#   queryset = Answers.objects.filter()
    pass


class MeetSheListView(ListAPIView):
    """首页右侧遇见它类视图"""
    # TODO 遇见它 数据库模型类 待处理
    pass


class ActivityCalendarListView(ListAPIView):
    """首页右下侧活动日历类视图"""
    # TODO 活动日历 数据库模型类 待处理
    pass


# url(r'news/(?P<id>\d+)', views.NewsDetailView.as_view())
class NewsViewSet(GenericViewSet, mixins.CreateModelMixin):
    """新闻详情类视图"""
    # 用户登录接口暂未引用
    # 查询优化，先查询新闻表、再查询两个评论表，再通过python 处理他们之间的关系
    queryset = News.objects.all().prefetch_related(Prefetch("comment_set", queryset=Comment.objects.all().prefetch_related('subs').order_by('-create_time')))
    lookup_url_kwarg = 'news_id'
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        """根据action选择对应的序列化器"""
        if self.action == 'comment':
            return serializers.CommentSerializer
        else:
            return serializers.NewsDetailSerializer

    def get_permissions(self):
        """根据请求方法设置权限"""
        if self.request.method == 'GET':
            return []
        return super(NewsViewSet, self).get_permissions()

    def retrieve(self, request, *args, **kwargs):
        """获取新闻详情"""
        # 获取对象，会检查对象的权限
        instance = self.get_object()
        # 每次浏览新闻详情，对应的点击量加１
        orgin_click_count = instance.click_count
        new_click_count = orgin_click_count + 1
        news_id = instance.id
        News.objects.filter(id=news_id).update(click_count=new_click_count)

        # 序列化
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

    # detail为True，表示要处理具体与pk主键对应的BookInfo对象
    @action(methods=['post'], detail=False)
    def comment(self, request):
        """提交评论"""
        return self.create(request)


# url(r'authors/(?P<pk>\d+)/$', views.AuthorRecentView.as_view())
class AuthorRecentView(ListAPIView):
    """详情页作者动态类视图"""
    serializer_class = AuthorRecentSerializer

    def get_queryset(self):
        author_id = self.kwargs['pk']
        return News.objects.filter(author_id=author_id).order_by('-create_time').prefetch_related('author')[0:4]


# url(r"hotrecommend/", views.HotRecommendView.as_view())
class HotRecommendView(ListAPIView):
    """
    新闻详情页热门回答类视图
    根据新闻点击量的排行显示前4条
    """
    serializer_class = HotRecommendSerializer
    # 查询集为 没有删除的新闻列表按照点击量排行 取 0 1 2 3
    queryset = News.objects.filter(is_delete=False).order_by('click_count').select_related()[0:4]


class HotComplainView(ListAPIView):
    """
    新闻详情页 热门吐槽类视图
    查询集根据 吐槽模型类 查询 吐槽的评论量来排序 取0 1 2 3
    """
    # TODO 吐槽模型类 待数据库迁移有数据后处理
    pass



